# dao/alibabacloud.py
"""
这是阿里云的短信服务接口
"""

import os
from dotenv import load_dotenv

from alibabacloud_dysmsapi20170525.client import Client as Dysmsapi20170525Client
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_dysmsapi20170525 import models as dysmsapi_20170525_models
from alibabacloud_tea_util import models as util_models

load_dotenv()


class AlibabaCloudSMS:
    _instance = None
    _client = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super(AlibabaCloudSMS, cls).__new__(cls)
        return cls._instance

    def __init__(self):
        if self._client is None:
            self._init_client()

    def _init_client(self):
        """初始化阿里云客户端"""
        config = open_api_models.Config(
            access_key_id=os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID'],
            access_key_secret=os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET']
        )
        config.endpoint = os.environ['ALIBABA_CLOUD_SMS_ENDPOINT']  # 从环境变量获取端点
        self._client = Dysmsapi20170525Client(config)

    async def send_verification_code(self, phone_number: str, code: str, code_type: str) -> bool:
        """
        发送验证码短信
        :param phone_number: 手机号码
        :param code: 验证码
        :param code_type: 验证码类型 (register/login/reset)
        :return: 是否发送成功
        """
        try:
            # 验证签名名称
            sign_name = os.environ['ALIBABA_CLOUD_SMS_SIGN_NAME']
            if not sign_name:
                print("错误：未配置短信签名名称")
                return False

            # 根据验证码类型选择对应的模板
            template_codes = {
                "register": os.environ['ALIBABA_CLOUD_SMS_REGISTER_TEMPLATE_CODE'],
                "login": os.environ['ALIBABA_CLOUD_SMS_LOGIN_TEMPLATE_CODE'],
                "reset": os.environ['ALIBABA_CLOUD_SMS_CHANGE_PASSWORD_TEMPLATE_CODE']
            }
            
            template_code = template_codes.get(code_type)
            if not template_code:
                print(f"无效的验证码类型: {code_type}")
                return False

            request = dysmsapi_20170525_models.SendSmsRequest(
                phone_numbers=phone_number,
                sign_name=sign_name,
                template_code=template_code,
                template_param=f'{{"code":"{code}"}}'
            )

            response = await self._client.send_sms_with_options_async(
                request,
                util_models.RuntimeOptions()
            )

            # 检查发送结果
            if response.body.code == 'OK':
                return True
            else:
                print(f"短信发送失败: {response.body.message}")
                return False

        except Exception as error:
            print(f"发送短信时发生错误: {error}")
            if hasattr(error, 'data') and error.data:
                print(f"诊断信息: {error.data.get('Recommend')}")
            return False

    def send_verification_code_sync(self, phone_number: str, code: str) -> bool:
        """
        同步方式发送验证码短信
        :param phone_number: 手机号码
        :param code: 验证码
        :return: 是否发送成功
        """
        try:
            request = dysmsapi_20170525_models.SendSmsRequest(
                phone_numbers=phone_number,
                sign_name=os.environ['ALIBABA_CLOUD_SMS_SIGN_NAME'],
                template_code=os.environ['ALIBABA_CLOUD_SMS_TEMPLATE_CODE'],
                template_param=f'{{"code":"{code}"}}'
            )

            response = self._client.send_sms_with_options(
                request,
                util_models.RuntimeOptions()
            )

            # 检查发送结果
            if response.body.code == 'OK':
                return True
            else:
                print(f"短信发送失败: {response.body.message}")
                return False

        except Exception as error:
            print(f"发送短信时发生错误: {error}")
            if hasattr(error, 'data') and error.data:
                print(f"诊断信息: {error.data.get('Recommend')}")
            return False
